package com.recruit.recommend.service;

import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import com.alibaba.dashscope.utils.JsonUtils;
import io.reactivex.Flowable;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.scheduler.Schedulers;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
public class ChatAiServiceImpl implements ChatAiService {

    private final static Logger logger = LoggerFactory.getLogger(ChatAiServiceImpl.class);
    @Value("${ai.api.key}")
    private String apiKey;

    @Resource
    Generation generation;

    @Override
    public Flux<ServerSentEvent<String>> generate(String question, HttpServletResponse response) throws NoApiKeyException, InputRequiredException {
        Constants.apiKey = apiKey;
        // 构建消息对象
        Message message = Message.builder().role(Role.USER.getValue()).content(question).build();
        // 构建通义千问参数对象
        GenerationParam param = GenerationParam.builder()
                .model(Generation.Models.QWEN_PLUS)
                .messages(Arrays.asList(message))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .topP(0.8)
                .apiKey(apiKey)
                .build();

        // 执行文本生成操作，并流式返回结果
        Flowable<GenerationResult> result = generation.streamCall(param);
        return Flux.from(result)
                .map(m -> {
                    String content = m.getOutput().getChoices().get(0).getMessage().getContent();
                    return ServerSentEvent.<String>builder().data(content).build();
                })
                .publishOn(Schedulers.boundedElastic())
                .doOnError(e -> {
                    // 错误处理
                    Map<String, Object> map = new HashMap<>();
                    map.put("code", "400");
                    map.put("message", "has mistake " + e.getMessage());
                    try {
                        response.setContentType(MediaType.TEXT_EVENT_STREAM_VALUE);
                        response.setCharacterEncoding("UTF-8");
                        response.getOutputStream().print(JsonUtils.toJson(map));

                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                });
                }


}
